<template>
  <PageCaontainer
    show-back
    :showCollapse="false"
    @back="router.go(-1)"
    class="dashboard-edit-wrapper"
  >
    <template #title>
      <a-space size="mini">
        <span v-show="showName">{{ dashboardInfo.name }}</span>
        <a-input
          ref="nameInputRef"
          v-show="!showName"
          show-word-limit
          :max-length="50"
          v-model="dashboardInfo.name"
          @blur="showName = !showName"
        ></a-input>
        <IconEdit
          v-show="showName"
          :size="18"
          @click="nameEdit"
          :style="{ color: '#979797', fontWeight: '400' }"
        ></IconEdit>
      </a-space>
    </template>
    <template #extra>
      <a-space :size="12">
        <a-popover v-model:popup-visible="descVisible" trigger="click">
          <a-button type="text"> 添加描述 </a-button>
          <template #title>
            <span style="font-weight: 500; line-height: 22px; font-size: 14px"
              >添加描述</span
            >
          </template>
          <template #content>
            <a-space direction="vertical">
              <a-textarea
                v-model="dashboardInfo.tempDescription"
                :style="{ width: '300px', height: '72px', marginTop: '8px' }"
                placeholder="请输入"
                :max-length="200"
                allow-clear
                show-word-limit
              />
              <a-space :size="6" fill style="justify-content: flex-end">
                <a-button size="small" @click="descVisible = false"
                  >取消</a-button
                >
                <a-button
                  size="small"
                  type="primary"
                  @click="
                    dashboardInfo.description = dashboardInfo.tempDescription;
                    descVisible = false;
                  "
                  >确认</a-button
                >
              </a-space>
            </a-space>
          </template>
        </a-popover>
        <a-button @click="router.go(-1)"> 取消 </a-button>
        <a-button type="primary" @click="saveDashboard"> 保存 </a-button>
      </a-space>
    </template>
    <AGraphDraggablePage
      v-model="graphData"
      @add="addGraph"
      @delete="deleteGraph"
      @change="changeGraph"
    >
      <template #left>
        <LeftTree drag />
      </template>
      <template #right>
        <RightConfig :cardData="graphItem" @option-change="optionChange" />
      </template>
    </AGraphDraggablePage>
  </PageCaontainer>
  <DeleteModal v-model="deleteModelVisible" @delete="confirmDelete" />
</template>

<script lang="ts" setup>
import { ref, reactive, nextTick, provide, readonly, watch } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import PageCaontainer from '@/arco-components/PageContainer';
import { IconEdit, IconDelete } from '@arco-design/web-vue/es/icon';
import { AGraphDraggablePage } from '@dangojs/a-graph-card';
import LeftTree from './components/graphLeftTree/index.vue';
import RightConfig from './components/graphRightConfig/index.vue';
import API from '@/services';
import {
  GraphType,
  defaultGlobalModel,
  getDefaultConfigModel,
  TimeFrameType
} from './type';
import { quarterTimeFormater } from './hooks';
import { Message } from '@arco-design/web-vue';
import * as RouteNames from '@/router/consts';
import DeleteModal from './components/deleteModal/index.vue';
import { cloneDeep } from 'lodash';
const showName = ref(true);
const nameInputRef = ref();
const router = useRouter();
const route = useRoute();
const deleteModelVisible = ref(false);
const descVisible = ref(false);

watch(descVisible, (val) => {
  if (!val) {
    dashboardInfo.tempDescription = dashboardInfo.description;
  }
});
const dashboardInfo = reactive({
  name: '我的看板',
  description: '',
  tempDescription: ''
});
const graphData = ref<any[]>([]);
const graphItem = ref();

// 默认最小的时间粒度（timeframe）
const timeframe = ref(TimeFrameType.DAY);
// 暂时未用
const timeDisable = ref(false);
// 指标配置里的时间粒度（其它以此为准）
const currentTimeframe = ref(TimeFrameType.DAY);
provide('min-timeframe', readonly(timeframe));
provide('current-timeframe', readonly(currentTimeframe));
provide('time-disable', readonly(timeDisable));
// 更新指标时间粒度
provide('update-min-timeframe', (timeUnit: TimeFrameType) => {
  if (
    Object.keys(TimeFrameType).some((key) => TimeFrameType[key] === timeUnit)
  ) {
    timeframe.value = timeUnit;
  } else {
    timeframe.value = TimeFrameType.DAY;
  }
});
// 更新实时的时间粒度
provide('update-current-timeframe', (timeUnit: TimeFrameType) => {
  if (
    Object.keys(TimeFrameType).some((key) => TimeFrameType[key] === timeUnit)
  ) {
    currentTimeframe.value = timeUnit;
  } else {
    timeframe.value = TimeFrameType.DAY;
  }
});
const getMetricSettingFilter = async (id: number) => {
  const { code, data = {} } =
    await API.metricsModelRelation.getGetMetricsFilterById({ id: id });
  if (code === 200) {
    timeframe.value = currentTimeframe.value = (data.timeframe ||
      timeframe.value) as any;
    timeDisable.value = data.ifGroupBy === 2 ? true : false;
  }
};

// 点击图表获取单个图表数据
const changeGraph = (index: number, item: any) => {
  let type = item.cardConfig.metricsSetting.statisticalPeriod.type;
  let timeUnit = item.cardConfig.metricsSetting.statisticalPeriod.timeUnit;
  currentTimeframe.value =
    type === 'recent' ? timeUnit : type.includes('_to_') ? 'day' : type;
  graphItem.value = item;
};

// 获取已有图表数据(id存在的话)
const getListData = async () => {
  let id = route.params.id;
  if (!id) return;
  let params: any = {
    boardId: +id,
    reviewType: 2,
    boardConfig: {
      ...defaultGlobalModel
    }
  };
  const {
    code,
    data = {},
    msg
  } = await API.metricsBoard.postMetricsBoardView(params);
  if (code === 200) {
    dashboardInfo.name = data.name!;
    dashboardInfo.description = dashboardInfo.tempDescription =
      data.description!;
    graphData.value = (data.cards || []).map((item: any) => {
      quarterTimeFormater(item.cardConfig, TimeFrameType.MONTH);
      item.graphType = GraphType[item.cardConfig.type || 1];
      item.graphSize = item.graphType === 'NUMBER' ? 'SMALL' : 'MIDDLE';
      item.name = item.name;
      item.result = item.cardConfig.result;
      item.isFirst = item.cardConfig.isFirst;
      return item;
    });
  } else {
    Message.error(msg);
  }
};
getListData();

// 左侧拖拽生成默认图表
const addGraph = async (
  item: any,
  pos: { index: number; isFirst: boolean }
) => {
  const { index, isFirst } = pos;
  try {
    await getMetricSettingFilter(item.id);
    // 构造默认数值类型配置
    let cardConfig = getDefaultConfigModel(GraphType.NUMBER, timeframe.value);
    cardConfig.metricsSetting.metricsId = item.id;
    cardConfig.metricsSetting.metricsName = item.name;
    const defaultNumberData: any = {
      boardConfig: {
        ...defaultGlobalModel
      },
      card: {
        cardConfig,
        name: ''
      }
    };
    const {
      code,
      data = {},
      msg
    } = await API.metricsBoard.postMetricsBoardCardPreview(defaultNumberData);
    if (code === 200) {
      let detail: any = {
        isFirst,
        index,
        graphSize: 'SMALL',
        graphType: 'NUMBER',
        name: item.name,
        cardConfig: data.cardConfig,
        result: (data.cardConfig! as any).result
      };
      graphData.value.splice(index, 0, detail);
    } else {
      Message.error(msg);
    }
  } catch (error) {
    console.error(error);
  }
};
// 删除单个图表
let deleteIndex: number;
const deleteGraph = (index: number) => {
  deleteModelVisible.value = true;
  deleteIndex = index;
};
const confirmDelete = () => {
  graphItem.value = null;
  const nextItem = graphData.value[deleteIndex + 1];
  if (nextItem?.graphSize === 'SMALL' && nextItem?.isFirst === false) {
    nextItem.isFirst = true;
  }
  deleteIndex > -1 && graphData.value.splice(deleteIndex, 1);
  deleteModelVisible.value = false;
};

// 配置项变化更新(名称变化、类型变化、点击确定)
const optionChange = (data: any, type: string) => {
  if (!graphItem.value) return;
  if (type === 'nameChange') {
    graphItem.value.name = data.name;
  } else {
    graphItem.value.graphType = data.graphType;
    graphItem.value.graphSize = data.graphSize;
    let cardConfig = getDefaultConfigModel(data.type, currentTimeframe.value);
    graphItem.value.cardConfig = {};
    Object.keys(cardConfig).forEach((key) => {
      graphItem.value.cardConfig[key] = data[key];
    });
    graphItem.value.result = data.result;
    type === 'metricsChange' && (graphItem.value.name = data.name);
  }
  let index = graphData.value.findIndex(
    (item) => item.uuid === graphItem.value.uuid
  );
  graphData.value[index] = cloneDeep(graphItem.value);
};

// 编辑卡片名称
const nameEdit = () => {
  showName.value = !showName.value;
  nextTick(() => {
    nameInputRef.value.focus();
  });
};

// 保存看板
const saveDashboard = async () => {
  console.log(graphData.value, 'ppp');
  if (!dashboardInfo.name) {
    Message.warning('看板名称不能为空');
    return;
  }
  if (!graphData.value.length) {
    Message.warning('请添加图表数据');
    return;
  }
  if (graphData.value.some((item) => !item.name)) {
    Message.warning('图表名称不能为空');
    return;
  }
  let params = {
    name: dashboardInfo.name,
    description: dashboardInfo.description,
    cards: graphData.value.map((item, index) => {
      item.cardConfig.isFirst = item.isFirst;
      return {
        name: item.name,
        cardConfig: item.cardConfig
      };
    }),
    boardConfig: {
      chosenMetricsIds: graphData.value.map(
        (item) => item.cardConfig.metricsSetting.metricsId
      ),
      conditions: undefined,
      dateCondition: undefined
    }
  };
  let id = +route.params.id;
  if (id) {
    const { code, msg } = await API.metricsBoard.putMetricsBoardById(
      { id },
      params
    );
    if (code === 200) {
      Message.success('保存成功');
      router.go(-1);
    } else {
      Message.error(msg);
    }
  } else {
    const { code, data, msg } = await API.metricsBoard.postMetricsBoard(params);
    if (code === 200) {
      Message.success('保存成功');
      router.replace({ name: RouteNames.ROUTER_MY_DASHBOARD });
    } else {
      !data && Message.error(msg);
    }
  }
};
</script>

<style lang="scss" scoped></style>

<style lang="scss">
.dashboard-edit-wrapper {
  position: fixed;
  top: 0;
  z-index: 11;
  .arco-popover-popup-arrow {
    display: block;
  }
  .arco-trigger-arrow {
    width: 12px;
    height: 12px;
  }
  .card-drag-center * {
    box-sizing: border-box;
  }
  .a-page-container-header {
    border-bottom: 1px solid #eee;
    box-shadow: 0px 3px 6px 0px rgba(51, 53, 59, 0.06);
    height: 60px;
    box-sizing: border-box;
    display: flex;
    align-items: center;
    .a-page-container-page-header {
      flex: 1;
      padding: 0;
    }
    .arco-page-header-wrapper {
      padding: 0 18px;
    }
  }
  .a-page-container-content {
    padding: 0;
  }
  // .card-drag-wrapper .card-drag-content {
  //   display: flex;
  //   flex-direction: column;
  // }
  // .card-drag-content-body {
  //   flex: 1;
  // }
  .undefined-graph.graph-wrapper {
    padding: 0;
    .graph-inner {
      border: none;
    }
  }
}
.graph-content,
.graph-wrapper {
  box-sizing: border-box;
}
.arco-select-view-multiple .arco-select-view-inner .arco-select-view-tag {
  border: none;
  background: #eff1f7;
  border-radius: 0.1875rem;
}
</style>
